﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using Radiation.Common;

namespace Radiation___IM
{
    public class AESManager
    {
        public static AESManager _manager;

        public static void Init()
        {
            _manager = new AESManager();
            _manager.createKeys();
        }

        public static AESManager Instance
        {
            get
            {
                return _manager;
            }
        }

        // Dynamic part

        public byte[] Key;
        public byte[] IV;

        private ICryptoTransform m_enc;
        private ICryptoTransform m_dec;

        public AESManager()
        {
        }

        public void createKeys()
        {
            Aes aes = Aes.Create();
            Key = aes.Key;
            IV = aes.IV;
        }

        private void init()
        {
            Aes aes = Aes.Create();
            aes.Key = Key;
            aes.IV = IV;
            m_enc = aes.CreateEncryptor(Key, IV);
            m_dec = aes.CreateDecryptor(Key, IV);
        }

        public string[] Decrypt(string base64payload)
        {
            string[] decrypted = base64payload.Split(new char[] { ';' });

            for (int i = 0; i < decrypted.Length; i++)
            {
                if (decrypted[i].Length > 0)
                {
                    if (m_dec == null)
                    {
                        if (Key != null && IV != null)
                            init();
                        else
                        {
                            Logger.Instance["error"].add("AESManager - Decrypt - Null m_dec & aes init data");
                            return null;
                        }
                    }

                    MemoryStream msDecrypt = new MemoryStream(Convert.FromBase64String(decrypted[i]));
                    CryptoStream csDecrypt = new CryptoStream(msDecrypt, m_dec, CryptoStreamMode.Read);
                    StreamReader srDecrypt = new StreamReader(csDecrypt);

                    string final = srDecrypt.ReadToEnd();

                    srDecrypt.Close();
                    csDecrypt.Close();
                    msDecrypt.Close();

                    init();

                    decrypted[i] = final;
                }
            }

            return decrypted;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="to_encrypt"></param>
        /// <returns>Base64 String</returns>
        public string Encrypt(string to_encrypt)
        {
            if (m_dec == null)
            {
                if (Key != null && IV != null)
                    init();
                else
                {
                    Logger.Instance["error"].add("AESManager - Encrypt - Null m_dec & aes init data");
                    return null;
                }
            }

            MemoryStream msEncrypt = new MemoryStream();
            CryptoStream csEncrypt = new CryptoStream(msEncrypt, m_enc, CryptoStreamMode.Write);
            StreamWriter swEncrypt = new StreamWriter(csEncrypt);

            swEncrypt.Write(to_encrypt);
            swEncrypt.Flush();
            csEncrypt.FlushFinalBlock();
            string to_return = Convert.ToBase64String(msEncrypt.ToArray());

            swEncrypt.Close();
            csEncrypt.Close();
            msEncrypt.Close();

            init();

            return to_return+";";
        }
    } 
}
